using System;
using System.Collections.Generic;
namespace TJDevHouse.Starcraft.Game
{
	/// <summary> Represents a unit type in StarCraft.
	/// 
	/// TODO: hit points are wrong for buildings. Not really a problem since this is type data, 
	/// instances should have accurate data.
	/// 
	/// Note: Minerals and Gas and considered unit types.
	/// 
	/// 
	/// TODO: get the whatBuilds, requiredUnits, requireTech attributes from StarCraft.
	/// </summary>
	public class UnitTypeSpec
	{
		public UnitTypeSpec()
		{
			UnitsBuilt = new List<UnitTypeSpec>();
		}

		virtual public List<UnitTypeSpec> UnitsBuilt { get; set; }

		/// <summary>unit type identifier </summary>
		virtual public int ID { get; set; }

		/// <summary>
		/// The unit type that this spec represents
		/// </summary>
		virtual public UnitType UnitType { get; set; }

		/// <summary>
		/// The default race of this unit.
		/// </summary>
		virtual public RaceTypes.Race Race { get; set; }

		/// <summary>the name of the type </summary>
		virtual public System.String Name {get; set;}

		/// <summary>
		/// Minerals cost
		/// </summary>
		virtual public int MineralsCost {get; set;}

		/// <summary>
		/// Gas cost
		/// </summary>
		virtual public int GasCost{get; set;}

		/// <summary>
		/// 
		/// </summary>
		virtual public int MaxHitPoints { get; set; }
		virtual public int MaxShields { get; set; }
		virtual public int MaxEnergy { get; set; }
		virtual public int BuildTime { get; set; }
		virtual public bool CanAttack { get; set; }
		virtual public bool CanMove { get; set; }
		virtual public int TileWidth { get; set; }
		virtual public int TileHeight { get; set; }
		virtual public int SupplyRequired { get; set; }
		virtual public int SupplyProvided { get; set; }
		virtual public int SightRange { get; set; }
		virtual public int GroundMinRange { get; set; }
		virtual public int GroundMaxRange { get; set; }
		virtual public int GroundDamage { get; set; }
		virtual public int AirRange { get; set; }
		virtual public int AirDamage { get; set; }
		virtual public bool IsABuilding { get; set; }
		virtual public bool IsAFlyer { get; set; }
		virtual public bool IsASpellCaster { get; set; }
		virtual public bool IsAWorker { get; set; }
		virtual public UnitType WhatBuilds { get; set; }
		virtual public bool IsACenter
		{
			get
			{
				return UnitType == UnitType.Protoss_Nexus || UnitType == UnitType.Terran_Command_Center || UnitType == UnitType.Zerg_Hatchery;
			}
		}

		/// <summary>
		/// Whether or not this unit is an air defence building
		/// </summary>
		public bool IsAirDefenceBuilding
		{
			get
			{
				return Race.GetAirDefenceUnitType() == UnitType;
			}
		}

		/// <summary>
		/// Whether or not this unit is a ground defence building
		/// </summary>
		public bool IsGroundDefenceBuilding
		{
			get
			{
				return Race.GetGroundDefenceUnitType() == UnitType;
			}
		}

		/// <summary>
		/// Whether or not this unit builds units of the given type
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public bool CanBuild(UnitType type)
		{
			//TODO implement CanBuild
			throw new NotImplementedException();
		}

		public bool CanBuild(UnitType type, UnitTypeSpec spec)
		{
			return ((UnitType)spec.WhatBuilds == UnitType);
		}

		/// <summary> Parses the unit types.</summary>
		public static Dictionary<UnitType, UnitTypeSpec> GetUnitTypes(System.String unitTypeData)
		{
			Dictionary<UnitType, UnitTypeSpec> types = new Dictionary<UnitType, UnitTypeSpec>();

			System.String[] unitTypes = unitTypeData.Split(":".ToCharArray());
			bool first = true;

			foreach (String unitType in unitTypes)
			{
				if (first)
				{
					first = false;
					continue;
				}

				System.String[] attributes = unitType.Split(";".ToCharArray());
				UnitTypeSpec type = new UnitTypeSpec();

				type.ID = System.Int32.Parse(attributes[0]);
				type.UnitType = (UnitType)type.ID;
				type.Race = Races.GetRaceByBWAPIRaceID(System.Int32.Parse(attributes[1]));

				//Console.WriteLine(type.UnitType + " has race id of " + System.Int32.Parse(attributes[1]));

				type.Name = attributes[2];
				type.MineralsCost = System.Int32.Parse(attributes[3]);
				type.GasCost = System.Int32.Parse(attributes[4]);
				type.MaxHitPoints = System.Int32.Parse(attributes[5]);
				type.MaxShields = System.Int32.Parse(attributes[6]);
				type.MaxEnergy = System.Int32.Parse(attributes[7]);
				type.BuildTime = System.Int32.Parse(attributes[8]);
				type.CanAttack = System.Int32.Parse(attributes[9]) == 1;
				type.CanMove = System.Int32.Parse(attributes[10]) == 1;
				type.TileWidth = System.Int32.Parse(attributes[11]);
				type.TileHeight = System.Int32.Parse(attributes[12]);
				type.SupplyRequired = System.Int32.Parse(attributes[13]);
				type.SupplyProvided = System.Int32.Parse(attributes[14]);
				type.SightRange = System.Int32.Parse(attributes[15]);
				type.GroundMaxRange = System.Int32.Parse(attributes[16]);
				type.GroundMinRange = System.Int32.Parse(attributes[17]);
				type.GroundDamage = System.Int32.Parse(attributes[18]);
				type.AirRange = System.Int32.Parse(attributes[19]);
				type.AirDamage = System.Int32.Parse(attributes[20]);
				type.IsABuilding = System.Int32.Parse(attributes[21]) == 1;
				type.IsAFlyer = System.Int32.Parse(attributes[22]) == 1;
				type.IsASpellCaster = System.Int32.Parse(attributes[23]) == 1;
				type.IsAWorker = System.Int32.Parse(attributes[24]) == 1;
				type.WhatBuilds = (UnitType) System.Int32.Parse(attributes[25]);

				//System.Console.Out.WriteLine(type.Id + " " + type.whatBuilds);

				types.Add(type.UnitType, type);
			}

			return types;
		}

		public override System.String ToString()
		{
			return Race + ":" + Name;
			//return "id:" + ID + " race:" + Race + " name:" + Name + " minCost:" + MineralsCost + " gasCost:" + GasCost + " hitPoints:" + MaxHitPoints + " shields:" + MaxShields + " energy:" + MaxEnergy + " buildTime:" + BuildTime + " canMove:" + CanMove + " canAttack:" + CanAttack + " width:" + TileWidth + " height:" + TileHeight + " supplyRequired:" + SupplyRequired + " supplyProvided:" + SupplyProvided + " sight:" + SightRange + " groundMaxRange:" + GroundMaxRange + " groundMinRange:" + GroundMinRange + " groundDamage:" + GroundDamage + " airRange:" + AirRange + " airDamage:" + AirDamage + " building:" + IsABuilding + " flyer:" + IsAFlyer + " spellcaster:" + IsASpellCaster + " worker:" + IsAWorker + " whatBuilds:" + WhatBuilds;
		}
	}
}